import numpy as np

from pynumpak.integrate import inner_product
from pynumpak.linalg import Vector
from pynumpak.type import Interval


class Func:
    def compute(self, x):
        pass

    def __call__(self, x):
        if hasattr(x, '__len__'):
            ans = []
            for k in range(len(x)):
                ans.append(self.compute(x[k]))
            return ans
        else:
            return self.compute(x)


class Polynomial(Func):
    def __init__(self, vec: Vector):
        self.coe = vec

    def compute(self, x: float):
        s = self.coe[-1]
        for i in range(2, len(self.coe) + 1):
            s *= x
            s += self.coe[-i]
        return s


class Legendre(Func):
    def __init__(self, coe, ab: Interval = None):
        if type(coe) == int:
            n = coe
            coe = np.zeros(n + 1)
            coe[n] = 1

        self.leg = np.polynomial.legendre.Legendre(coe, domain=ab)
        ab = (-1, 1) if ab is None else ab
        self.squared_norm = inner_product(self.leg, self.leg, ab)

    def compute(self, x: float):
        return self.leg(x)
